The design of the protocol was one of the most important parts of the project as it heavily affected the design of the rest of the system. The protocol defines the format in which the clients and server communicate; any client program wishing to communicate with a JAM server must follow the rules of this protocol consistently. By defining a protocol, this also means that the server need not worry about a particular client's implementation -- as long as their messages follow the protocol specification.

At its most basic view, the JAM protocol operates in a very simple manner. A client connects to the server and they then exchange messages until the connection is closed. Any number of clients can be connected to the server and exchanging messages at a time. 

The following sections will deal with the syntax (the grammar and format) and semantics (the underlying meaning) of the of the protocol.

\subsection{Syntax}

Interaction between the JAM server and client operates by exchanging text-based messages, with each new line sent representing a new message. Choosing a text-based protocol allows each message to be human readable, allowing for simpler debugging and testing. Each message is split into a number of components, separated by a colon, as shown in the following example. Following these components should be a next-line character to signal that the message has ended.

\begin{alltt}
<KEYWORD>:<TRANSACTION ID>:<ARGUMENT 1>:<ARGUMENT 2>:...:<ARGUMENT N>
\end{alltt}

\begin{itemize}
\item \textbf{Keyword}

This component identifies the particular type of message. Each different type of message has its own unique keyword. These keywords follow a particular convention that will be discussed later on in this section.

\item \textbf{Transaction ID}

This component identifies a particular pair of messages. As a number of messages expect responses, a response to those messages must have a matching transaction ID. This means that if a number of requests are sent at the same time, they can be answered in any order as long as the transaction ID matches. This number should start from zero and increment with each pair of sent and received messages, per client.

\item \textbf{Arguments}

Following the keyword and transaction ID is a number of arguments. The exact number of arguments depends on the type of message; there is no lower or upper limit on the amount of arguments sent. Each argument must be separated by a colon and cannot be empty.
\end{itemize}

An example message exchange for joining a channel and sending a message is shown below.
\begin{alltt}
Client: CA\_JOIN:0:\#chat
Server: CA\_JOIN:0:TRUE

Client: CA\_MSG:1:\#chat:Hello, world!
Server: CA\_MSG:1:TRUE
\textbf{(Turn this into a sequence diagram - with more details, 
perhaps move to interaction section?)}
\end{alltt}

This message format was chosen mostly for its simplicity and readability, something which is important when debugging the network components during the implementation stage. By making the protocol format as simple as possible, this also allows the component that interacts with it --- the network controller --- to be designed and implemented in a simpler way than if the protocol was more complex.

As our separation character --- a colon --- may be potentially used in some sent message’s arguments, this character must be escaped to prevent it from being detected as a message component separator when it is in fact part of the argument. This is achieved by doubling the colon (i.e: an emoticon such as ‘:)’ becomes ‘::)’) upon sending the message. When the message is then received and being parsed, adjacent colons should be combined together to get the original argument. As no message component can be blank, this should not cause any problems with the legitimate message separators.

Any binary data that is to be sent as an argument – such as avatar images – should be encoded using Base64 encoding. This is same type of encoding used to attach files to emails and thus is widely used and supported. This type of encoding translates binary data to the ASCII character set, allowing it to easily be sent using our text-based protocol in an efficient, readable manner.

The protocol itself defines no strict limitations in terms of message length, aiming to be as flexible as possible for any protocol evolution in terms of the number of arguments and types of data sent. It is up to the particular client and server implementation to negotiate any limitations, however it is assumed that the server will simply disconnect the client if a message starts to exceed a particular sane size limit (e.g: 1024 characters for sending a chat message, etc).

\subsection{Semantics}

Now that we have defined the format of the protocol messages, we can begin to discuss how the server and client should handle and respond to particular messages. Each message sent, either by the client or server, must receive a response with a matching \textbf{keyword} and \textbf{transaction ID}. The response that is sent depends on the type of message. Requiring each message to be met with a response ensures that the sender knows that the receiver has actually received and processed that particular message. 

Messages are separated into two distinct types, which are the following:

\begin{itemize}
\item \textbf{Action Messages}

These types of messages are single actions such as logging in, sending a message or updating a password, or any kind of action that expects only a ``success'' or ``failure'' response. Upon receiving an action message, the receiver should process it and respond with same keyword, same transaction ID and a single argument containing either “TRUE” or “FALSE” to indicate if the action completed successfully. Client action messages have keywords prefixed with ``CA\_'' and server action messages have keywords prefixed with ``SA\_''.

\item \textbf{Request Messages}

These are messages which expect some sort of data response such as a list of users currently in a channel, getting the current status of a user or a list of users in your contact list. As before, the receiver should respond to this type of message with the same keyword and transaction ID, however after which any arguments depend on the particular message that is sent. It is intended that only the client shall make request messages however there is no particular restriction against the server making request messages in the protocol. Client request messages have keywords prefixed with ``CR\_''.
\end{itemize}

Messages are split into these two types for the sake of logical categorisation -- action messages being messages that ask the receiver to perform some sort of specific action, and request messages being messages that perform some sort of query on the receiver, expecting a data response. This helped when defining the protocol specification, as we could think more clearly about the types of responses that should be returned along with what the ordering of that response should be. It also helped to simplify the network architecture as explained later on in this report.

\subsection{Error Handling}

Any message received that is syntactically valid but either with a keyword that is unknown to the server or has incorrect arguments should be met with a response as if it was an action message with a ``failure'' response (i.e: respond with the same keyword, transaction ID but only a ``FALSE'' argument). This allows both the server and client to fail gracefully while still sending a response that semantically makes sense. There is one issue with this in that the client will not be aware that they have sent a malformed message as it may just seem as if their request had failed – however this could be corrected be simply adding an action message that notifies the sender of the particular error.

Messages that are not syntactically correct (i.e: garbage or some other form of corrupted data) should be responded to by closing the connection. While this is not as graceful as the previous way of handling errors, it means that the server will not become over-encumbered as it tries to process potentially large amounts of random data.

\textbf{Heartbeat}

In order for the server to detect if a client is still connected, it will try to send a ``heatbeat'' action message – specifically ``\textit{SA\_PING}'' – every sixty seconds. Upon receiving this message, the client should respond with a ``success'' response, after which the server will wait for another sixty seconds before sending another heartbeat. If there is no response to this heartbeat after sixty seconds, the server will assume that that the client has disconnected and must log that user out.

\subsection{Interaction}

Once a client has established a connection to the server, the only commands it may initially perform are those which allow it to register a new account or login to an existing account – any other command should be met with a failure response. Once the client has logged in, either by using an existing account or by creating a new one, it may perform any action or request on the server. At the same time, the server may send actions or requests to the client itself, which the client must be prepared to process and respond to, including the heartbeat as explained in the above section. A particular user should only be able to login once, after which they must either logout or wait for the server to logout the account itself if it fails to send a heartbeat.

\subsection{Evolution}

Initially, we discussed the idea of using the protocol defined by last year’s team for this particular project, aiming to give us compatibility with their existing client and server. However, we decided against this in favour of creating our own protocol, mainly as it would give us more flexibility when it came to designing and implementing the client and server later on in the project. 

The first draft of the protocol specification defined the syntax along with some basic actions such as those required for logging in and sending messages. Additional actions and requests were added to the protocol as the server was designed and implemented, at which point it became obvious that splitting the messages into two different types --- actions and requests --- would make the protocol more clearly defined. Beyond this, the protocol has essentially remained the same as it was defined in the first draft; no issues have occurred due to its design.